package com.chinairi.mall.service.impl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.chinairi.common.annotation.DoPage;
import com.chinairi.common.utils.IdGenerator;
import com.chinairi.common.utils.ResponseUtil;
import com.chinairi.common.utils.UserSession;
import com.chinairi.mall.controller.viewobject.ProjectPlanReqVO;
import com.chinairi.mall.controller.viewobject.ReqModelVO;
import com.chinairi.mall.dao.*;
import com.chinairi.mall.error.BusinessException;
import com.chinairi.mall.error.EmBusinessError;
import com.chinairi.mall.model.*;
import com.chinairi.mall.service.IProjectPlanReqService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chinairi.mall.service.IProjectService;
import com.chinairi.mall.service.IUserCompanyInfoService;
import com.chinairi.mall.service.modelobject.CompanyTypeMO;
import com.chinairi.mall.service.modelobject.ProjectPlanReqApproveMO;
import com.chinairi.mall.service.modelobject.UserInfoToRedisMO;
import com.chinairi.mall.util.FileUtil;
import com.chinairi.mall.util.NumberFormatUtil;
import com.chinairi.mall.util.PurchaseUtils;
import com.chinairi.mall.util.VerificationCodeUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author gsl
 * @since 2020-09-19
 */
@Service
public class ProjectPlanReqServiceImpl extends ServiceImpl<ProjectPlanReqMapper, ProjectPlanReq> implements IProjectPlanReqService {

    @Autowired
    private ProjectPlanReqMapper projectPlanReqMapper;
    @Autowired
    private ProjectPlanReqDetailMapper projectPlanReqDetailMapper;
    @Autowired
    private IUserCompanyInfoService userCompanyInfoService;
    @Autowired
    private ServiceOrderProjectMapper serviceOrderProjectMapper;
    @Autowired
    private ProjectMapper projectMapper;
    @Autowired
    private MaterialMapper materialMapper;
    @Autowired
    private SysUserServiceImpl sysUserService;
    @Autowired
    private ProjectServiceImpl projectService;
    @Autowired
    private ProjectPlanPurchaseMapper projectPlanPurchaseMapper;
    @Autowired
    private ContractMaitainMapper contractMaitainMapper;
    @Autowired
    private ProjectPlanReqStorageMapper projectPlanReqStorageMapper;
    @Autowired
    private StorageAddressMapper storageAddressMapper;

    /**
     * 生成需求计划
     * whn
     *
     * @param projectPlanReqVO
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addPlanReq(ProjectPlanReqVO projectPlanReqVO) {
        if (projectPlanReqVO.getpId() == null || StringUtils.isEmpty(projectPlanReqVO.getpId())) {
            throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR, "项目Id为空");
        }
        if (projectPlanReqVO.getModelId() == null || StringUtils.isEmpty(projectPlanReqVO.getModelId())) {
            throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR, "模型Id为空");
        }
        ProjectPlanReq projectPlanReq = new ProjectPlanReq();
        //4位流水号
        String planReqId = NumberFormatUtil.numberFormat(4, projectPlanReqMapper.getPlanReqNo());
        BeanUtils.copyProperties(projectPlanReqVO, projectPlanReq);
        projectPlanReq.setPlanReqId(planReqId);
        Project projectById = projectMapper.selectById(projectPlanReq.getpId());
        projectPlanReq.setUciDbid(projectById.getUciDbid());
        projectPlanReq.setCreateUser(UserSession.getUserId());
        projectPlanReq.setCreateTime(new Date());
        projectPlanReq.setPlanReqStatus(0);
        //设置初始状态
        projectPlanReq.setApproveStatus("0");
        projectPlanReqMapper.insert(projectPlanReq);
        if (projectPlanReqVO.getProjectPlanReqDetailList().size() > 0) {
            projectPlanReqDetailMapper.batchInsert(projectPlanReqVO.getProjectPlanReqDetailList().stream().peek((list) -> {
                float number = list.getPlanReqNum();
                list.setPlanDetailId(UUID.randomUUID().toString().replace("-", ""));
                list.setPlanReqNumNow(number);
                list.setPlanReqId(planReqId);
                list.setPlanStorageNum((float) 0);
                list.setPlanFlatNum((float) 0);
                list.setPlanAlreadyBuyNum((float) 0);
                list.setPlanShouldBuyNum(number);
                list.setPlanAddShoppingCarNum((float) 0);
                list.setPlanCollectedNum((float) 0);
                list.setPlanEstimatePrice(new BigDecimal(0));
                list.setPlanEstimateMoney(new BigDecimal(0));
            }).collect(Collectors.toList()));
        }
        ServiceOrderProject serviceOrderProject = new ServiceOrderProject();
        serviceOrderProject.setSopId(projectPlanReqVO.getSopId());
        serviceOrderProject.setSopStatus(4);
        serviceOrderProjectMapper.updateById(serviceOrderProject);
        Project project = new Project();
        project.setpId(projectPlanReqVO.getpId());
        project.setpStatus("4");
        projectMapper.updateById(project);
    }

    @Override
    public void exportExcel(HttpServletResponse response, ReqModelVO reqModelVo) throws IOException {
        String fileName = "需求建议计划详单.xlsx";
        fileName = URLEncoder.encode(fileName, "UTF-8");
        response.setCharacterEncoding("utf8");
        response.setContentType("application/vnd.ms-excel");
        response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
        response.setHeader("Pragma", "public");
        response.setHeader("Cache-Control", "no-store");
        response.addHeader("Cache-Control", "max-age=0");
        reqModelExportExcel(response, reqModelVo);
    }

    public void reqModelExportExcel(HttpServletResponse response, ReqModelVO reqModelVo) throws IOException {
        InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("templates/excel/export.xlsx");
        ServletOutputStream out = response.getOutputStream();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日");
        ExcelWriter excelWriter = EasyExcel.write(out).withTemplate(inputStream).build();
        WriteSheet writeSheet = EasyExcel.writerSheet(0, "sheet").build();
        Map<String, Object> map = new HashMap<>(4);
        map.put("projectName", reqModelVo.getProjectName());
        map.put("creator", UserSession.getUserName());
        map.put("createTime", simpleDateFormat.format(new Date()));
        map.put("modelName", reqModelVo.getModelName());
        excelWriter.fill(map, writeSheet);
        excelWriter.fill(reqModelVo.getExcelReqDetailList(), writeSheet);
        excelWriter.finish();

    }

    /**
     * 批量设置收货地址和到货时间
     *
     * @param projectPlanReqDetailList
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateAddressAndTime(List<ProjectPlanReqDetail> projectPlanReqDetailList) {
        projectPlanReqMapper.batchUpdateById(projectPlanReqDetailList);
    }

    /**
     * 更新
     *
     * @param projectPlanReqDetail
     */
    @Override
    public void updateDetail(ProjectPlanReqDetail projectPlanReqDetail) {
        projectPlanReqDetailMapper.updateById(projectPlanReqDetail);
    }

    /**
     * 新增一条需求计划中的物料
     *
     * @param projectPlanReqDetail
     */
    @Override
    public void addMaterial(ProjectPlanReqDetail projectPlanReqDetail) {
        Integer reqMatNum = projectPlanReqDetailMapper.countReqMat(projectPlanReqDetail.getPlanReqId(),
                projectPlanReqDetail.getPlanMatCode());
        if (reqMatNum != null && reqMatNum > 0) {
            throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR, "已有该物料");
        }

        Material material = materialMapper.selectById(projectPlanReqDetail.getPlanMatCode());

        projectPlanReqDetail.setPlanDetailId(UUID.randomUUID().toString().replace("-", ""));
        projectPlanReqDetail.setPlanMatDescription(material.getMatName());
        projectPlanReqDetail.setPlanMeasureUnit(material.getMatMeasuerUnit());
        projectPlanReqDetail.setPlanAssistMeasure(material.getMatAssistMeasure());
        projectPlanReqDetail.setPlanStorageNum((float) 0);
        projectPlanReqDetail.setPlanFlatNum((float) 0);
        projectPlanReqDetail.setPlanAlreadyBuyNum((float) 0);
        projectPlanReqDetail.setPlanShouldBuyNum((float) 0);
        projectPlanReqDetail.setPlanAddShoppingCarNum((float) 0);
        projectPlanReqDetail.setPlanCollectedNum((float) 0);
        projectPlanReqDetail.setPlanEstimatePrice(new BigDecimal(0));
        projectPlanReqDetail.setPlanEstimateMoney(new BigDecimal(0));

        projectPlanReqDetail.setCreateUser(UserSession.getUserId());
        projectPlanReqDetail.setCreateTime(new Date());

        projectPlanReqDetailMapper.insert(projectPlanReqDetail);
    }

    /**
     * 获取某一需求计划下的详细物料信息
     *
     * @param planReqId
     * @return
     */
    @Override
    public ProjectPlanReqVO getReqDetail(String planReqId) {
        List<ProjectPlanReqDetail> projectPlanReqDetailList = projectPlanReqDetailMapper.getList(planReqId, "");
        ProjectPlanReq projectPlanReq = projectPlanReqMapper.selectById(planReqId);
        if (projectPlanReq == null) {
            throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR, "数据为空");
        }
        ProjectPlanReqVO projectPlanReqVO = new ProjectPlanReqVO();
        BeanUtils.copyProperties(projectPlanReq, projectPlanReqVO);
        projectPlanReqVO.setProjectPlanReqDetailList(projectPlanReqDetailList);
        return projectPlanReqVO;
    }

    /**
     * 删除一条计划下的物料
     *
     * @param planDetailId
     * @return
     */
    @Override
    public void deleteByDetailId(String planDetailId) {
        projectPlanReqDetailMapper.deleteById(planDetailId);
    }

    /**
     * 更新审核状态
     *
     * @param projectPlanReq
     */
    @Override
    public void updateStatus(ProjectPlanReq projectPlanReq) {
        projectPlanReq.setApproveUser(UserSession.getUserId());
        projectPlanReq.setApproveTime(new Date());
        projectPlanReqMapper.updateById(projectPlanReq);
    }

    /**
     * 获取本用户单位下的需求计划列表
     *
     * @param
     * @return
     */
    @Override
    @DoPage
    public List<ProjectPlanReq> getList(ProjectPlanReq projectPlanReq) {
        String userId = UserSession.getUserId();
        UserInfoToRedisMO userInfoToRedisMO = sysUserService.getUserInfoFromRedis(UserSession.getUserId());
        if (userInfoToRedisMO == null || "".equals(userInfoToRedisMO.getUciDbid())) {
            throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR, "没有企业信息");
        }
        QueryWrapper<ProjectPlanReq> wrapper = new QueryWrapper<>();
        //查询企业标志，物资公司：1 普通企业: 0
        Integer uciCompCharacter = contractMaitainMapper.selectUciCompCharacter(UserSession.getUserId());
        wrapper.eq(uciCompCharacter != null && uciCompCharacter == 0, "UCI_DBID", userInfoToRedisMO.getUciDbid())
                .eq(projectPlanReq.getpId() != null && !"".equals(projectPlanReq.getpId()), "P_ID", projectPlanReq.getpId())
                .orderByAsc("APPROVE_STATUS")
                .orderByDesc("CREATE_TIME");
        List<ProjectPlanReq> projectPlanReqList = projectPlanReqMapper.selectList(wrapper);
        if (projectPlanReqList.size() == 0) {
            throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR, "暂无需求计划");
        }
        return projectPlanReqList;
    }

    /**
     * 删除某一需求计划
     *
     * @param planReqId
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteById(String planReqId) {
        projectPlanReqMapper.deleteById(planReqId);
        Map<String, Object> map = new HashMap<>(1);
        map.put("PLAN_REQ_ID", planReqId);
        projectPlanReqDetailMapper.deleteByMap(map);
    }

    /**
     * 提交某条记录进入审核，该接口将这条记录的状态字段置为3-审核中。
     *
     * @param projectPlanReq
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addApprove(ProjectPlanReq projectPlanReq) {
        projectPlanReq.setSubmitter(UserSession.getUserId());
        projectPlanReqMapper.updateById(projectPlanReq);
    }

    /**
     * 获取待审核的数据记录，此时审核状态应为3-审核中，或者除了状态为0的其余所有记录均返回即可。
     *
     * @param projectPlanReqApproveMo
     * @return
     */
    @Override
    @DoPage
    public List<ProjectPlanReqApproveMO> getNeedApprove(ProjectPlanReqApproveMO projectPlanReqApproveMo) {
        return projectPlanReqMapper.getNeedApprove(projectPlanReqApproveMo);
    }

    /**
     * 更新某条计划的审核状态
     *
     * @param projectPlanReqApproveMo
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateApprove(ProjectPlanReqApproveMO projectPlanReqApproveMo) {
        ProjectPlanReq projectPlanReq = new ProjectPlanReq();
        BeanUtils.copyProperties(projectPlanReqApproveMo, projectPlanReq);
        projectPlanReq.setApproveUser(UserSession.getUserId());
        projectPlanReq.setApproveTime(new Date());
        projectPlanReqMapper.updateById(projectPlanReq);
        if ("1".equals(projectPlanReqApproveMo.getApproveStatus())) {
            QueryWrapper<ProjectPlanPurchase> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("PLAN_REQ_ID", projectPlanReq.getPlanReqId());
            projectPlanPurchaseMapper.delete(queryWrapper);
            ProjectPlanPurchase projectPlanPurchase = new ProjectPlanPurchase();
            String purchaseId = NumberFormatUtil.numberFormat(4, projectPlanPurchaseMapper.getPlanPurchaseNo());
            projectPlanPurchase.setPlanReqId(projectPlanReq.getPlanReqId());
            projectPlanPurchase.setPlanPurchaseId(purchaseId);
            projectPlanPurchase.setCreateUserName(UserSession.getUserName());
            projectPlanPurchase.setCreateUser(UserSession.getUserId());
            projectPlanPurchase.setCreateTime(new Date());
            projectPlanPurchase.setUpdateUser(UserSession.getUserId());
            projectPlanPurchase.setUpdateTime(new Date());
            //插入采购计划主表
            projectPlanPurchaseMapper.insert(projectPlanPurchase);
            //绑定需求计划下详情下的物料绑定到这个采购计划
            QueryWrapper<ProjectPlanReqDetail> queryWrapper1 = new QueryWrapper<>();
            queryWrapper1
                    .eq("PLAN_REQ_ID", projectPlanReq.getPlanReqId());
            List<ProjectPlanReqDetail> projectPlanReqDetailList = projectPlanReqDetailMapper.selectList(queryWrapper1);
            List<ProjectPlanReqStorage> projectPlanReqStorageList = new ArrayList<>();
            for (ProjectPlanReqDetail projectPlanReqDetail : projectPlanReqDetailList) {
                Map<String, Object> resultMap = PurchaseUtils.getFlatNum(projectPlanReqDetail.getPlanReqNum(), projectPlanReqDetail.getPlanReqId(), projectPlanReqDetail.getPlanMatCode());
                projectPlanReqDetail.setPlanPurchaseId(purchaseId);
                projectPlanReqDetail.setPlanStorageNum(Float.valueOf(resultMap.get("allstor").toString()));
                projectPlanReqDetail.setPlanFlatNum(Float.valueOf(resultMap.get("allflat").toString()));
                projectPlanReqStorageList.addAll((ArrayList) resultMap.get("list"));
            }
            if (projectPlanReqStorageList.size() > 0){
                projectPlanReqStorageMapper.batchInsert(projectPlanReqStorageList);
            }
            projectPlanReqDetailMapper.updatePurchaseId(projectPlanReqDetailList);
        }
    }

    /**
     * 用户自己新增需求计划
     *
     * @param projectPlanReq
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String addNewReq(ProjectPlanReq projectPlanReq) {
        String planReqId = VerificationCodeUtil.DateCreate(new Date());
        projectPlanReq.setPlanReqId(planReqId);
        Project projectById = projectMapper.selectById(projectPlanReq.getpId());
        projectPlanReq.setpName(projectById.getpName());
        projectPlanReq.setModelId("无");
        projectPlanReq.setModelName("无");
        projectPlanReq.setUciDbid(projectById.getUciDbid());
        projectPlanReq.setCreateUser(UserSession.getUserId());
        projectPlanReq.setCreateTime(new Date());
        projectPlanReq.setPlanReqStatus(0);
        //设置初始状态
        projectPlanReq.setApproveStatus("0");
        projectPlanReqMapper.insert(projectPlanReq);
        Project project = new Project();
        project.setpId(projectPlanReq.getpId());
        project.setpStatus("6");
        projectMapper.updateById(project);
        return planReqId;
    }

    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    @Override
    public Map<String,Object> updateProjectPlanReq(ProjectPlanReqVO projectPlanReqVO){
        if (StringUtils.isEmpty(projectPlanReqVO.getpId())) {
            return ResponseUtil.toWarningMessage("没有数据",false);
        }
       QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("P_ID",projectPlanReqVO.getpId());
        ProjectPlanReq projectPlanReq = projectPlanReqMapper.selectOne(queryWrapper);
        Map<String,Object> map = new HashMap<>(1);
        map.put("PLAN_REQ_ID",projectPlanReq.getPlanReqId());
        projectPlanReqDetailMapper.deleteByMap(map);
        List<ProjectPlanReqDetail> projectPlanReqDetailList = projectPlanReqVO.getProjectPlanReqDetailList();
        if (projectPlanReqDetailList !=null &&!projectPlanReqDetailList.isEmpty()){
            for (ProjectPlanReqDetail projectPlanReqDetail :projectPlanReqDetailList){
                projectPlanReqDetail.setPlanReqId(projectPlanReq.getPlanReqId());
                projectPlanReqDetail.setPlanDetailId(IdGenerator.UUID());
                projectPlanReqDetail.setUpdateTime(new Date());
                projectPlanReqDetail.setUpdateUser(UserSession.getUserId());
                projectPlanReqDetail.setPlanStorageNum((float) 0);
                projectPlanReqDetail.setPlanFlatNum((float) 0);
                projectPlanReqDetail.setPlanAlreadyBuyNum((float) 0);
                projectPlanReqDetail.setPlanShouldBuyNum(projectPlanReqDetail.getPlanReqNum());
                projectPlanReqDetail.setPlanAddShoppingCarNum((float) 0);
                projectPlanReqDetail.setPlanCollectedNum((float) 0);
                projectPlanReqDetail.setPlanEstimatePrice(new BigDecimal(0));
                projectPlanReqDetail.setPlanEstimateMoney(new BigDecimal(0));
                projectPlanReqDetailMapper.insert(projectPlanReqDetail);
            }
        }
        projectPlanReq.setApproveStatus("0");
        projectPlanReq.setPlanReqStatus(0);
        projectPlanReq.setUpdateTime(new Date());
        projectPlanReq.setUpdateUser(UserSession.getUserId());
        projectPlanReqMapper.updateById(projectPlanReq);
        return ResponseUtil.toSuccessMessage("保存成功",projectPlanReqVO);
    }

    @Override
    public ProjectPlanReqAddress getProjectAddressOrStorageAddress(String planReqId) {
        QueryWrapper<StorageAddress> wrapper = new QueryWrapper<>();
        wrapper.orderByDesc(    "SA_DBID");
        List<StorageAddress> storageAddresses = storageAddressMapper.selectList(wrapper);
        String projectAddress = projectMapper.getProjectAddress(planReqId);
        ProjectPlanReqAddress projectPlanReqAddress = new ProjectPlanReqAddress();
        projectPlanReqAddress.setPlanAddress(projectAddress);
        projectPlanReqAddress.setStorageAddresses(storageAddresses);
        return projectPlanReqAddress;
    }
}
